import time
from multiprocessing import Queue, Process
from threading import Thread


def async_task(f):
    def wrapper(*args, **kwargs):
        thr = Thread(target=f, args=args, kwargs=kwargs)
        thr.start()
    return wrapper


def async_task_process(f):
    def wrapper(*args, **kwargs):
        p = Process(target=f, name='my_task_process', args=args, kwargs=kwargs)
        p.start()
    return wrapper


class TaskInfo:

    # delay: 延迟执行时间, 单位:秒
    def __init__(self, task_func=None, params=None, callback=None, delay=0):
        self.task_func = task_func
        self.callback = callback
        self.params = params
        self.delay = delay


@async_task
def run_task(task_info):
    try:
        if task_info.delay > 0:
            time.sleep(task_info.delay)

        func = task_info.task_func
        if func == 'EXIT':
            return
        if not func:
            print('请设置要执行的任务')
        if task_info.params:
            result = func(**task_info.params)
        else:
            result = func()
        if task_info.callback:
            task_info.callback(result)

    except BaseException as e:
        print(e)


class AsyncTask:

    def __init__(self):
        self.__task_que = Queue()
        self.__task_running = False

    def put_task(self, task_info):
        self.__task_que.put(task_info)
        if not self.__task_running:
            self.__task_running = True
            self.start()

    @async_task_process
    def start(self):
        while True:
            try:
                task_info = self.__task_que.get(timeout=300)
            except BaseException as e:
                print(e)
                return
            if not isinstance(task_info, TaskInfo):
                print('参数类型错误!!!')
                continue

            run_task(task_info)

            if task_info.task_func == 'EXIT':
                return

    def stop(self):
        self.put_task(TaskInfo(task_func='EXIT'))


# def my_test():
#     print('test函数执行开始')
#     time.sleep(3)
#     print('test 函数执行结束')
#     return '执行成功', '1'
#
#
# def task_callback(result):
#     print('callback result:', result)
#
#
# def my_print(i):
#     print('task:' + str(i))
#
#
# def test():
#     task = AsyncTask()
#     task.put_task(TaskInfo(task_func=my_test, callback=task_callback, delay=2))
#
#     for i in range(10):
#         ti = TaskInfo()
#         ti.task_func = my_print
#         ti.params = {
#             'i': i,
#         }
#         task.put_task(ti)
#         print(i)
#         time.sleep(1)
#
#     task.stop()
#
#
# test()
